package com.cryann.mqttserver.config;

import com.cryann.mqttserver.mqttProcess.ProcessSelector;
import com.cryann.mqttserver.mqttProcess.mqttMsgHandler.MqttMsgCheckHandler;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.mqtt.MqttFixedHeader;
import io.netty.handler.codec.mqtt.MqttMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Optional;

/**
 * @author cRyann
 * @date 2018/12/4 0004 17:40
 * @description:
 */
@Component
@ChannelHandler.Sharable
@Slf4j
public class NettyServerHandler extends SimpleChannelInboundHandler {

    @Autowired
    ProcessSelector processSelector;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("ChannelActive from [{}]", ctx.channel().remoteAddress());
        super.channelActive(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error(cause.getMessage());
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.warn("Channel is disconnected because:[{}]" ,ctx.channel().remoteAddress());
        super.channelInactive(ctx);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.debug("server Rec msg:[{}]", msg);
        Optional.ofNullable(msg).ifPresent(m -> {
            Optional.ofNullable(MqttMsgCheckHandler.mqttHandler()).ifPresent(t -> t.handleMessage((MqttMessage) m));
            MqttFixedHeader fixedHeader = ((MqttMessage) m).fixedHeader();
            Optional.ofNullable(fixedHeader).ifPresent(fix ->
                    Optional.ofNullable(
                            processSelector.getProves(fix)).ifPresent(process -> process.process(ctx.channel(), m)
                    )
            );
        });

    }
}
